package
{
	import flash.display.Graphics;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.net.URLRequest;
	import flash.net.navigateToURL;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	import flash.utils.getTimer;

	[SWF(backgroundColor=0x777777, width=465, height=465, frameRate=60)]
	public class game1 extends Sprite
	{

		private var _balls:Array;

		private var _ballsLayer:Sprite;

		private var _retry:Button;

		private var _time:uint;

		private var _timeText:TextField;

		private var _tweet:Button;

		public function game1()
		{
			_ballsLayer = new Sprite();
			addChild(_ballsLayer);

			_timeText = new TextField();
			_timeText.defaultTextFormat = new TextFormat(null, 16);
			_timeText.mouseEnabled = false;
			addChild(_timeText);

			_timeText.text = "Click to Start!";

			_ballsLayer.addEventListener(MouseEvent.CLICK, clickHandler);
			var g:Graphics = _ballsLayer.graphics;
			g.clear();
			g.beginFill(0x777777);
			g.drawRect(0, 0, 465, 465);
			g.endFill();

			_tweet = new Button("Tweet!");
			_tweet.y = 430;
			_tweet.x = 60;
			_tweet.visible = false;
			_tweet.addEventListener(MouseEvent.CLICK, tweetHandler);
			addChild(_tweet);

			_retry = new Button("Retry");
			_retry.y = 430;
			_retry.x = 10;
			_retry.visible = false;
			_retry.addEventListener(MouseEvent.CLICK, retryHandler);
			addChild(_retry);
		}

		private function clickHandler(e:MouseEvent):void
		{
			_ballsLayer.removeEventListener(MouseEvent.CLICK, clickHandler);
			setupStage();
			nextHandler(null);
		}

		private function enterFrameHandler(e:Event):void
		{
			_timeText.text = ((getTimer() - _time) / 1000).toFixed(2) + "ms";
		}

		private function nextHandler(e:Event):void
		{
			if (e === null)
			{
				_timeText.text = "";
				_time = getTimer();
				addEventListener(Event.ENTER_FRAME, enterFrameHandler);
			}
			else
			{
				(e.currentTarget as Ball).removeEventListener("next", nextHandler);
			}

			var ball:Ball = _balls.shift();
			if (ball !== null)
			{
				ball.focus();
			}
			else
			{
				removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
				_retry.visible = true;
				_tweet.visible = true;
				enterFrameHandler(null);
			}
		}

		private function retryHandler(e:MouseEvent):void
		{
			_retry.visible = false;
			_tweet.visible = false;
			_timeText.text = "Click to Start!";
			_ballsLayer.addEventListener(MouseEvent.CLICK, clickHandler);
		}

		private function setupStage():void
		{
			var balls:Array = [];

			for (var i:int = 25; i >= 1; i--)
			{
				var ball:Ball = new Ball(i, Math.random() * 2 + 2);
				_ballsLayer.addChild(ball);

				ball.x = Math.random() * (465 - ball.width) + ball.width / 2;
				ball.y = Math.random() * (465 - ball.height) + ball.height / 2;

				ball.addEventListener("next", nextHandler);
				balls[i - 1] = ball;
			}

			_balls = balls;
			_balls[0].focus();
		}

		private function tweetHandler(e:MouseEvent):void
		{
			var uri:Array = [];
			uri.push("http://twitter.com/home?status=");
			uri.push(encodeURIComponent("25クリックのクリア時間は" + _timeText.text + "でした。"));
			uri.push(encodeURIComponent(" http://wonderfl.net/c/a "));
			uri.push(encodeURIComponent(" #25click "));

			navigateToURL(new URLRequest(uri.join("")));
		}
	}
}

import flash.display.Graphics;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.GlowFilter;
import flash.geom.Rectangle;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.text.engine.ElementFormat;
import flash.text.engine.FontDescription;
import flash.text.engine.TextBlock;
import flash.text.engine.TextElement;
import flash.text.engine.TextLine;
import flash.utils.getTimer;

class Button extends Sprite
{

	public function Button(text:String)
	{
		var tf:TextField = new TextField();
		tf.defaultTextFormat = new TextFormat(null, 16, 0x0);
		tf.text = text;
		tf.border = true;
		tf.borderColor = 0;
		tf.autoSize = TextFieldAutoSize.LEFT;
		tf.mouseEnabled = false;

		var shape:Shape = new Shape();
		var g:Graphics = shape.graphics;
		g.clear();
		g.beginFill(0xffffff, 1);
		g.drawRect(0, 0, tf.width, tf.height);
		g.endFill();

		addChild(shape);
		addChild(tf);

		buttonMode = true;
		useHandCursor = true;
	}
}

class Ball extends Sprite
{

	private static var _baseFilter:Array = [new GlowFilter(0x000000, 0.4, 16, 16, 1, 2)];

	private static var _numberFilter:Array = [new GlowFilter(0xffffff, 1, 2, 2, 2, 4)];

	private var _base:Sprite;

	private var _focusTime:uint;

	private var _focused:Boolean;

	private var _line:TextLine;

	private var _puffTime:uint;

	private var _ring:Shape;

	private var _scale:Number;

	public function Ball(number:Number, scale:Number)
	{
		scaleX = scaleY = _scale = scale;

		var c:uint = 0;
		while (c === 0)
		{
			c = (Math.random() < 0.5 ? 0xff0000 : 0) +
				(Math.random() < 0.5 ? 0xff00 : 0) +
				(Math.random() < 0.5 ? 0xff : 0);
		}
		_base = new Sprite();
		addChild(_base);
		var g:Graphics = _base.graphics;
		g.beginFill(c);
		g.drawCircle(0, 0, 15);
		g.endFill();
		_base.filters = _baseFilter;
		_base.addEventListener(MouseEvent.MOUSE_DOWN, downHandler);

		var format:ElementFormat = new ElementFormat();
		format.fontSize = 20;
		format.fontDescription = new FontDescription("Arial");
		var element:TextElement = new TextElement(String(number), format);
		var block:TextBlock = new TextBlock(element);
		var line:TextLine = block.createTextLine(null);
		line.filters = _numberFilter;
		line.mouseEnabled = line.mouseChildren = false;
		line.addEventListener(MouseEvent.MOUSE_DOWN, downHandler);
		addChild(line);
		_line = line;

		var bounds:Rectangle = line.getRect(this);
		line.x = (30 - bounds.width) / 2 - 15 - bounds.x;
		line.y = (30 - bounds.height + line.descent) / 2 - 15 - bounds.y;

		_ring = new Shape();
		addChild(_ring);
	}

	public function focus():void
	{
		_focused = true;
		_focusTime = getTimer() + 1000;
		addEventListener(Event.ENTER_FRAME, focusEnterFrameHandler);
	}

	private function downHandler(e:MouseEvent):void
	{
		if (!_focused)
		{
			if (_scale > 0.5)
			{
				_scale *= 0.7;
				scaleX = scaleY = _scale;

			}
			return;
		}
		mouseEnabled = mouseChildren = false;
		dispatchEvent(new Event("next"));

		_ring.graphics.clear();
		removeEventListener(Event.ENTER_FRAME, focusEnterFrameHandler);
		_base.removeEventListener(MouseEvent.MOUSE_DOWN, downHandler);
		_line.removeEventListener(MouseEvent.MOUSE_DOWN, downHandler);
		addEventListener(Event.ENTER_FRAME, puffEnterFrameHandler);
		_puffTime = getTimer();
	}

	private function focusEnterFrameHandler(e:Event):void
	{
		var g:Graphics = _ring.graphics;
		g.clear();

		var f:Number = (getTimer() - _focusTime) % 1000;
		if (f < 0)
		{
			return;
		}
		if (f > 500)
		{
			return;
		}

		f = (f /= 500) * f;

		g.clear();
		g.lineStyle(5 + 15 * f, 0xffff00, 0.2 * (1 - f));
		g.drawCircle(0, 0, 15 + 35 * f);
		g.endFill();
	}

	private function puffEnterFrameHandler(e:Event):void
	{
		var f:Number = getTimer() - _puffTime;
		if (f > 500)
		{
			f = 500;
			removeEventListener(Event.ENTER_FRAME, puffEnterFrameHandler);
			parent.removeChild(this);
			return;
		}

		f = (f /= 500) * f * f;
		alpha = 1 - f;
		scaleX = scaleY = _scale + _scale * f * 2;
	}
}
